package com.samphanie.security.security.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.samphanie.common.constants.SystemConstants;
import com.samphanie.security.config.IgnoreUrlsConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.List;
import java.util.Objects;


/**
 * 白名单路径访问时需要移除JWT请求头
 *
 * @author ZSY
 * @email 1451691457@qq.com
 */
@Component
@RequiredArgsConstructor
public class IgnoreUrlsRemoveJwtFilter extends OncePerRequestFilter {

    private final IgnoreUrlsConfig ignoreUrlsConfig;

    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain chain) throws ServletException, IOException {

        HttpServletRequestWrapper requestWrapper = null;
        AntPathMatcher pathMatcher = new AntPathMatcher();
        String uri = request.getRequestURI();
        // 白名单路径移除JWT请求头
        String path = URLUtil.getPath(uri);
        List<String> ignoreUrls = ignoreUrlsConfig.getUrls();
        for (String ignoreUrl : ignoreUrls) {
            if (pathMatcher.match(ignoreUrl, path)) {
                requestWrapper = new HttpServletRequestWrapper(request) {
                    @Override
                    public String getHeader(String name) {
                        // 先从原本的Request中获取头，如果为空且名字为token，则从参数中查找并返回
                        String superHeader = super.getHeader(name);
                        if (SystemConstants.JWT_TOKEN_HEADER.equals(name) && StrUtil.isNotEmpty(superHeader)) {
                            return "";
                        }
                        return superHeader;
                    }
                };
            }
        }
        chain.doFilter(Objects.requireNonNullElse(requestWrapper, request), response);
    }
}
